import tkinter as tk
from tkinter import *
import Functionpage
from Login import *
import Login
from DeviceRegistration import *
import CSCommunication
from tkinter import scrolledtext
from threading import Thread
import Reinforce

##############
#author:张子路#
##############

class UserUI():
    def __init__(self):
        self.CheckList=[0,0,0,0,0,0,0]
        self.MissionList=[]        #当前任务列表
        self.ExecuteSate=False
        self.CheckOutput=''

    def GnerateOutput(self,HostCheckOpt,SecurityCheckOpt,PatchCheckOpt,NetCheckOpt,BackDoorCheckOpt,SelfRunCheckOpt,SoftWareCheckOpt):
        try:         #根据多选器生成需要进行的任务
            if HostCheckOpt.get():
                self.CheckList[0]=1
            if SecurityCheckOpt.get():
                self.CheckList[1]=1
            if PatchCheckOpt.get():
                self.CheckList[2]=1
            if NetCheckOpt.get():
                self.CheckList[3]=1
            if BackDoorCheckOpt.get():
                self.CheckList[4]=1
            if SelfRunCheckOpt.get():
                self.CheckList[5]=1
            if SoftWareCheckOpt.get():
                self.CheckList[6]=1
            self.MissionList.append([-1,self.CheckList])
            if not self.ExecuteSate:
                self.ExecuteSate=True
                self.ExecuteMissionList()      #开始执行任务列表中的任务
            self.CheckList=[0,0,0,0,0,0,0]
        except Exception as e:
            logging.error("检查功能执行失败 {0}".format(e), exc_info=True)

    def LogOut(self,Window):
        try:         #返回登录界面
            Window.destroy()
            LoginUI=Login.LoginStart()
            LoginUI.start()
        except Exception as e:
            logging.error("返回登录界面失败 {0}".format(e), exc_info=True)

    def TextViewOut(self,OutText,State):
        MissionStr=''
        while(1):
            try:
                if self.OutputeText:         #确定线程执行输出时，输出文本框已创立，否则循环等待
                    pass
            except AttributeError:
                pass
            except Exception as e:
                logging.error("返回登录界面失败 {0}".format(e), exc_info=True)
                break
            else:
                break
        try:        #获取当前任务信息
            if self.MissionList!=[]:
                if self.MissionList[0][1][0]==1:
                    MissionStr=MissionStr+'主机信息核查 '
                if self.MissionList[0][1][1]==1:
                    MissionStr=MissionStr+'安全策略核查 '
                if self.MissionList[0][1][2]==1:
                    MissionStr=MissionStr+'补丁信息核查 '
                if self.MissionList[0][1][3]==1:
                    MissionStr=MissionStr+'网络信息核查 '
                if self.MissionList[0][1][4]==1:
                    MissionStr=MissionStr+'后门核查 '
                if self.MissionList[0][1][5]==1:
                    MissionStr=MissionStr+'自启动项核查 '
                if self.MissionList[0][1][6]==1:
                    MissionStr=MissionStr+'服务项核查 '
        except Exception as e:
            logging.error("获取当前任务失败 {0}".format(e), exc_info=True)
        try:
            if State==1:
                self.OutputeText.configure(state=tk.NORMAL)    #输出核查结果
                OutputText="本机检查任务（{0}）执行结果：\n".format(MissionStr)+OutText+'\n'
                self.OutputeText.insert(END,OutputText)
                self.OutputeText.configure(state=tk.DISABLED)
            elif State==2:
                self.OutputeText.configure(state=tk.NORMAL)   #输出执行任务情况
                OutputText="正在执行本机检查任务（{0}），还有{1}个任务待执行：\n".format(MissionStr,len(self.MissionList))+OutText+"\n"
                self.OutputeText.insert(END,OutputText)
                self.OutputeText.configure(state=tk.DISABLED)
            elif State==3:
                self.OutputeText.configure(state=tk.NORMAL)    #清空输出
                self.OutputeText.delete('1.0',END)
                self.OutputeText.configure(state=tk.DISABLED)
            elif State==4:
                self.OutputeText.configure(state=tk.NORMAL)
                self.OutputeText.insert(END,'安全加固完成。\n\n')
                self.OutputeText.configure(state=tk.DISABLED)
            else:
                print("状态传输错误，输出执行失败，请检查。")
        except Exception as e:
            logging.error("输出失败 {0}".format(e), exc_info=True)

    def ExecuteMissionList(self):
        try:
            if self.MissionList!=[]:
                self.TextViewOut('',2)
                self.CreatTread(self.ExecuteMission,arg=[self.MissionList[0]])        #创建线程执行任务
            else:
                self.ExecuteSate=False
        except Exception as e:
            logging.error("执行核查任务失败 {0}".format(e), exc_info=True)

    def ExecuteMission(self,Mission):
        try:     #执行任务
            fun=Functionpage.Function()    #调用文件进行核查处理
        except Exception as e:
            logging.error("连接文件Functionpage.py失败 {0}".format(e), exc_info=True)
        try:
            Output=fun.HaddleMCheck(Mission[0],Mission[1])
            self.TextViewOut(Output,State=1)
        except Exception as e:
            logging.error("执行核查任务失败 {0}".format(e), exc_info=True)
        finally:
            del self.MissionList[0]
            if self.MissionList==[]:
                self.ExecuteSate=False
            else:
                self.ExecuteMissionList()


    def DiviceRegist(self):
        try:
            DeviceRegist=DeviceRegistUI()       #调用文件创建设备注册界面
            DeviceRegist.Start()
        except Exception as e:
            logging.error("连接设备注册界面失败 {0}".format(e), exc_info=True)

    def CreatTread(self,Function,arg=None):
        try:         #创建线程
            if arg==None:
                CreatedThread=Thread(target=Function)
            else:
                CreatedThread=Thread(target=Function,args=arg)
            CreatedThread.setDaemon(True)

            CreatedThread.start()
        except Exception as e:
            logging.error("执行核查任务失败 {0}".format(e), exc_info=True)


    def StartMission(self):
        StartCheckList=[0,0,0,0,0,0,0]
        try:
            Communication=CSCommunication.CSCommunication()     #获取未执行的任务
            Mission=Communication.GetMission()
        except Exception as e:
            logging.error("获取待执行任务失败 {0}".format(e), exc_info=True)
        taskid=[]
        for iteam in self.MissionList:
            taskid.append(iteam[0])
        else:
            for iteam in Mission:
                if '主机信息核查' in iteam[1]:
                    StartCheckList[0]=1
                if '安全策略核查' in iteam[1]:
                    StartCheckList[1]=1
                if '补丁信息核查' in iteam[1]:
                    StartCheckList[2]=1
                if '网络信息核查' in iteam[1]:
                    StartCheckList[3]=1
                if '后门核查' in iteam[1]:
                    StartCheckList[4]=1
                if '自启动项核查' in iteam[1]:
                    StartCheckList[5]=1
                if '服务项核查' in iteam[1]:
                    StartCheckList[6]=1
                if iteam[0] not in taskid:
                    self.MissionList.append([iteam[0],StartCheckList])
                StartCheckList=[0,0,0,0,0,0,0]
        try:
            if not self.ExecuteSate:
                self.ExecuteSate=True
                self.ExecuteMissionList()
        except Exception as e:
            logging.error("执行任务失败 {0}".format(e), exc_info=True)

    def Reinforce(self):
        try:            #进行安全加固
            ReinClass=Reinforce.Reinforce()
        except Exception as e:
            logging.error("连接文件Reinforce.py失败 {0}".format(e), exc_info=True)
        try:
            ReinClass.Start()
        except Exception as e:
            logging.error("安全加固失败 {0}".format(e), exc_info=True)
        self.TextViewOut('',State=4)

    def Start(self):
        self.StartUI()

    def StartUI(self):
        try:
            Mainui=tk.Tk()      #创建用户主界面

            Mainui.geometry('800x600')
            Mainui.title("基线检查")

            LabelTitle=tk.Label(Mainui,text='欢迎使用基线检查平台',font=("楷体",20,"bold"),width=20,height=1)
            LabelTitle.place(x=400,y=10,anchor='n')

            LogOut=tk.Button(Mainui,text='退出登录',command=lambda:self.LogOut(Mainui))
            LogOut.place(x=10,y=10)

            DiviceRegist=tk.Button(Mainui,text='设备注册',command=lambda:self.DiviceRegist())
            DiviceRegist.place(x=10,y=100)

            LabelSelect=tk.Label(Mainui,text='选择核查项目',font=("楷体",15))
            LabelSelect.place(x=400,y=100,anchor='n')


            DiviceRegist=tk.Button(Mainui,text='重新获取任务',command=lambda:self.StartMission())
            DiviceRegist.place(x=700,y=100)

            HostCheckOpt = tk.BooleanVar()
            HostMCheck = tk.Checkbutton(Mainui, text='主机信息核查', variable=HostCheckOpt,font=("楷体",16,"bold"))
            HostMCheck.place(x=100,y=150,anchor='n')

            SecurityCheckOpt = tk.BooleanVar()
            SecurityMCheck = tk.Checkbutton(Mainui, text='安全策略核查', variable=SecurityCheckOpt,font=("楷体",16,"bold"))
            SecurityMCheck.place(x=300,y=150,anchor='n')

            PatchCheckOpt = tk.BooleanVar()
            PatchMCheck = tk.Checkbutton(Mainui, text='补丁信息核查', variable=PatchCheckOpt,font=("楷体",16,"bold"))
            PatchMCheck.place(x=500,y=150,anchor='n')

            NetCheckOpt = tk.BooleanVar()
            NetMCheck = tk.Checkbutton(Mainui, text='网络信息核查', variable=NetCheckOpt,font=("楷体",16,"bold"))
            NetMCheck.place(x=700,y=150,anchor='n')

            BackDoorCheckOpt = tk.BooleanVar()
            BackDoorMCheck = tk.Checkbutton(Mainui, text='后门核查', variable=BackDoorCheckOpt,font=("楷体",16,"bold"))
            BackDoorMCheck.place(x=100,y=200,anchor='n')

            SelfRunCheckOpt = tk.BooleanVar()
            SelfRunMCheck = tk.Checkbutton(Mainui, text='自启动项核查', variable=SelfRunCheckOpt,font=("楷体",16,"bold"))
            SelfRunMCheck.place(x=300,y=200,anchor='n')

            SoftWareCheckOpt = tk.BooleanVar()
            SoftWareMCheck = tk.Checkbutton(Mainui, text='服务项核查', variable=SoftWareCheckOpt,font=("楷体",16,"bold"))
            SoftWareMCheck.place(x=500,y=200,anchor='n')

            self.SubmitMCheck=tk.Button(Mainui,text='开始核查',command=lambda:self.GnerateOutput(HostCheckOpt,SecurityCheckOpt,PatchCheckOpt,NetCheckOpt,BackDoorCheckOpt,SelfRunCheckOpt,SoftWareCheckOpt))
            self.SubmitMCheck.place(x=400,y=250,anchor='n') #生成按钮，发生点击事件时调用函数执行选中的任务

            LabelTitle=tk.Label(Mainui,text='核查结果',font=("楷体",15))
            LabelTitle.place(x=400,y=300,anchor='n')

            Clear=tk.Button(Mainui,text='清空输出',command=lambda:self.TextViewOut('',State=3))
            Clear.place(x=500,y=300)

            Rein=tk.Button(Mainui,text='安全加固',command=lambda:self.Reinforce())
            Rein.place(x=650,y=300)


            self.OutputeText=tk.scrolledtext.ScrolledText(Mainui,width=100,height=17,state=tk.DISABLED,command=self.CreatTread(self.StartMission))
            self.OutputeText.place(x=400,y=350,anchor='n')    #使界面生成时，创建线程获取未完成任务并执行

            Mainui.mainloop()
        except Exception as e:
            logging.error("主界面创建失败 {0}".format(e), exc_info=True)


if __name__ == '__main__':
    login=LoginStart()         #执行该文件时调用生成登录界面
    login.start()

